#ifndef __IMU_42686_H__
#define __IMU_42686_H__

#define D_SPI_READ_OP			( 1 << 7 )

#ifndef M_PI
  #define M_PI 3.14159265358979323846f
#endif 

typedef enum {
	//FOR ICM42686 register
	DEVICE_CONFIG		= 0x11, //device_config(spi_mode,soft_reset_config),page 61 of 105
	PWR_MGMT0			= 0x4E, //page 72 of 105
	GYRO_CONFIG0        = 0x4F, //GYRO_FS_SEL[bit5-7],GYRO_ODR[bit0-3],page 58 of 105
	ACCEL_CONFIG0       = 0x50, //page 74 of 105
	GYRO_CONFIG1        = 0x51, //temperature LPF  and gyro UI filter and DEC2_M2 filter order,page 75 of 105
	GYRO_ACCEL_CONFIG0  = 0x52, //set gyro and accel LPF bandwidth
	ACCEL_CONFIG1       = 0x53, //page 77 of 105
	TMST_CONFIG         = 0x54, //page 77 of 105
	FIFO_CONFIG1        = 0x5F, //page 79 of 105
	FIFO_CONFIG2        = 0x60, //page 79 of 105
	FIFO_CONFIG3        = 0x61, //page 79 of 105
	FSYNC_CONFIG		= 0x62,
	WHO_AM_I            = 0x75, //page 84 of 105
	REG_BANK_SEL 		= 0x76, //page 84 of 105
	TEMP_OUT_ADDR		= 0x1D, // temperature
	ACCEL_OUT_ADDR		= 0x1F, //page 58 of 105 // 0x1F for ACCEL_DATA_X1(X0,Y1,Y0,Z1,Z0)
	GYRO_OUT_ADDR		= 0x25, // GYRO_DATA_X1

	//interrupt and FIFO reg config
	INT_CONFIG			= 0x14,
	FIFO_CONFIG			= 0x16,
	FIFO_SOURCE0		= 0x65,
	INTF_CONFIG0		= 0x4C,
	INT_CONFIG0			= 0x63,
	INT_CONFIG1			= 0x64,
	INT_SOURCE0			= 0x65,
	INT_SOURCE1			= 0x66,
	INT_SOURCE3			= 0x68,
	///end of register
} E_GYRO_REG_ADDR;

/**
 * Definition of Register Data
 */
typedef enum {
	// CONFIG register
	#define DLPF(v) 	((v) << 0)	// For the DLPF to be used, FCHOICE_B[1:0] is 2â€™b00.
	FSYNC_TEMP			= (1 << 3),
	FSYNC_GYRO_X		= (2 << 3),
	FSYNC_GYRO_Y		= (3 << 3),
	FSYNC_GYRO_Z		= (4 << 3),
	FSYNC_ACCEL_X		= (5 << 3),
	FSYNC_ACCEL_Y		= (6 << 3),
	FSYNC_ACCEL_Z		= (7 << 3),
	FIFO_DROP			= (1 << 6),
	FIFO_REPLACE		= (0 << 6),
	// GYRO_CONFIG register
	FCHOICE_B_x1		= (1 << 0),
	FCHOICE_B_10		= (2 << 0),
	FCHOICE_B_00		= (0 << 0),
	GYRO_FS_250 		= (0 << 3),
	GYRO_FS_500 		= (1 << 3),
	GYRO_FS_1000		= (2 << 3),
	GYRO_FS_2000		= (3 << 3),
	// ACCEL_CONFIG register
	ACCEL_FS_2G 		= (0 << 3),
	ACCEL_FS_4G 		= (1 << 3),
	ACCEL_FS_8G 		= (2 << 3),
	ACCEL_FS_16G		= (3 << 3),
	ACCEL_DEC2_4		= (0 << 4),
	ACCEL_DEC2_8		= (1 << 4),
	ACCEL_DEC2_16		= (2 << 4),
	ACCEL_DEC2_32		= (3 << 4),
	// ACCEL_CONFIG2 register
	ACCEL_FCHOICE_B_1	= (1 << 3),
	ACCEL_FCHOICE_B_0	= (0 << 3),
	// INT_PIN_CFG register
	INT_FSYNC_EN		= (1 << 2), // FSYNC causes the interrupt
	INT_FSYNC_LOW		= (1 << 3), // FSYNC is active low
	INT_FSYNC_HIGH		= (0 << 3), // FSYNC is active high
	INT_RD2CLEAR		= (1 << 4), // any read clears interrupt status
	INT_PULSE			= (0 << 5), // interrupt is a 50us pulse
	INT_LATCH			= (1 << 5), // level is held until interrupt status is cleared
	INT_PUSHPULL		= (0 << 6), // INT pin is push-pull
	INT_OPEN			= (1 << 6), // INT pin is open drain
	INT_HIGH			= (0 << 7), // INT pin is active high
	INT_LOW 			= (1 << 7), // INT pin is active low
	// INT_ENABLE, INT_STATUS registers
	INT_RAW_RDY 		= (1 << 0),
	INT_GDRIVE			= (1 << 2),
	INT_FSYNC			= (1 << 3),
	INT_OVERFLOW		= (1 << 4),
	INT_WOM_Z			= (1 << 5),
	INT_WOM_Y			= (1 << 6),
	INT_WOM_X			= (1 << 7),
	INT_WOM 			= (INT_WOM_X | INT_WOM_Y | INT_WOM_Z),
	// USER_CTRL register
	CTRL_SIG_RST		= (1 << 0),
	CTRL_FIFO_RST		= (1 << 2),
	CTRL_FIFO_EN		= (1 << 6),
	// FIFO_EN register
	FIFO_ACCEL			= (1 << 3),
	FIFO_GYRO	 		= (1 << 4),
	// PWR_MGMT_1 register
	PWR_CLK_OSC 		= (0 << 0),
	PWR_CLK_PLL1		= (1 << 0),
	PWR_SLEEP			= (1 << 6),
	PWR_RESET			= (1 << 7),
	// SIGNAL_PATH_RESET register
	RESET_TEMP			= (1 << 0),
	RESET_ACCEL 		= (1 << 1),

	//ICM42686 register data
	SOFT_RESET_B0		= (1 << 0),
	BANK0_B0			= (0 << 0),
	GYRO_CONFIG0_DATA	= 0x03,//+-2000dps(default/8KHz)
	GYRO_CONFIG1_DATA	= 0X06,//1st order
	ACCEL_CONFIG0_DATA	= 0x06,
	ACCEL_CONFIG1_DATA	= 0x00,
	GYRO_ACCEL_CONFIG0_DATA = 0x00,
	PWR_MGMT0_DATA		= 0x0F,//
	FIFO_CONFIG1_DATA	= 0x03,
} E_GYRO_REG_DATA;


typedef struct _IMU_DATA
{
	unsigned char six_axis[12];
}IMU_DATA_T;

struct temperature
{
    float deg;
};

struct imu_acc
{
	float ax;
	float ay;
	float az;
};

struct imu_gry
{
	float gx;
	float gy;
	float gz;
};

struct icm42686_data {
    struct _temperature
	{
		unsigned short deg;
	}temperature;

	struct _acc
	{
		unsigned short x;
		unsigned short y;
		unsigned short z;
	}acc;

	struct _gyro
	{
		unsigned short x;
		unsigned short y;
		unsigned short z;
	}gyro;
};

#endif /* __IMU_42686_H__ */
